<template>
    <div class="tableRow">
        <el-row class="select-list" v-permission="'monitor:job:query'">
            <el-form :inline="true" ref="selectForm" :model="selectFormModel" :label-position="'right'"
                     label-width="80px" size="mini">
                <el-form-item label="任务名称" prop="jobName">
                    <el-input v-model="selectFormModel.jobName" placeholder="任务名称" style="width: 200px" clearable
                              @keyup.enter.native="onSearch"/>
                </el-form-item>
                <el-form-item label="任务分组" prop="jobGroup">
                    <el-select value="" v-model="selectFormModel.jobGroup" placeholder="任务分组"
                               @keyup.enter.native="onSearch">
                        <el-option label="默认" value="DEFAULT"/>
                        <el-option label="系统" value="SYSTEM"/>
                    </el-select>
                </el-form-item>
                <el-form-item label="任务状态" prop="status">
                    <el-select value="" v-model="selectFormModel.status" placeholder="任务状态" style="width: 200px">
                        <el-option label="正常" value="0"/>
                        <el-option label="停止" value="1"/>
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" icon="el-icon-search" size="mini" plain round @click="onSearch">搜索
                    </el-button>
                    <el-button type="warning" icon="el-icon-refresh" size="mini" plain round
                               @click="onRefreshSelectForm">重置
                    </el-button>
                </el-form-item>
            </el-form>
        </el-row>
        <el-row class="toolbar">
            <el-button type="primary" icon="el-icon-plus" size="mini" plain @click="handleAdd"
                       v-permission="'monitor:job:add'">
                新增
            </el-button>
            <el-button type="info" icon="el-icon-edit" :disabled="dialog.isBatchEditDisabled" size="mini" plain
                       @click="handleEdit" v-permission="'monitor:job:edit'"> 编辑
            </el-button>
            <el-button type="danger" icon="el-icon-delete" :disabled="dialog.isBatchRemoveDisabled" size="mini" plain
                       @click="handleBatchDelete" v-permission="'monitor:job:remove'"> 删除
            </el-button>
            <el-button type="warning" icon="fa fa-download" size="mini" plain @click="handleExport"
                       v-permission="'monitor:job:export'"> 导出
            </el-button>

            <el-button type="success" icon="fa fa-list" size="mini" plain
                       @click="handleJobLogsInfo" v-permission="'monitor:job:log'"> 日志
            </el-button>
        </el-row>
        <data-table ref="dataTable"
                    :api="getJobList"
                    :options="options"
                    :columns="columns"
                    :operates="operates"
                    :query="selectFormModel"
                    @handleSelectionChange="handleSelectionChange"
        />

        <el-dialog :title="dialog.title"
                   :visible.sync="dialog.dialogFormVisible"
                   :modal-append-to-body="false"
                   :destroy-on-close="false"
                   @close="closeDialog"
                   width="600px">
            <el-form :model="jobModel" ref="jobForm" label-width="100px" :rules="jobFormRules" size="small">
                <el-form-item label="任务名称" prop="jobName">
                    <el-input v-model="jobModel.jobName" placeholder="任务名称"/>
                </el-form-item>
                <el-form-item label="任务分组" prop="jobGroup">
                    <el-select value="" v-model="jobModel.jobGroup" placeholder="任务分组">
                        <el-option label="默认" value="DEFAULT"/>
                        <el-option label="系统" value="SYSTEM"/>
                    </el-select>
                </el-form-item>
                <el-form-item label="调用字符串" prop="invokeTarget">
                    <el-input v-model="jobModel.invokeTarget" placeholder="调用字符串"/>
                </el-form-item>
                <el-form-item label="cron表达式" prop="cronExpression">
                    <el-input v-model="jobModel.cronExpression" placeholder="cron表达式"/>
                </el-form-item>
                <el-form-item label="执行策略">
                    <el-radio-group v-model="jobModel.misfirePolicy">
                        <el-radio label="1">立即执行</el-radio>
                        <el-radio label="2">执行一次</el-radio>
                        <el-radio label="3">放弃执行</el-radio>
                    </el-radio-group>
                </el-form-item>

                <el-form-item label="并发执行">
                    <el-switch v-model="jobModel.concurrent" active-color="#13ce66" inactive-color="#ff4949"
                               active-text="允许"
                               inactive-text="禁止"
                               active-value="0"
                               inactive-value="1"/>
                </el-form-item>
                <el-form-item label="状态">
                    <el-switch v-model="jobModel.status" active-color="#13ce66" inactive-color="#ff4949"
                               active-text="正常"
                               inactive-text="停止"
                               active-value="0"
                               inactive-value="1"/>
                </el-form-item>
                <el-form-item label="备注" prop="remark">
                    <el-input v-model="jobModel.remark" placeholder="备注" maxlength="100"/>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialog.dialogFormVisible=false" size="medium">取 消</el-button>
                <el-button type="primary" @click="submitForm" size="medium">确 定</el-button>
            </div>
        </el-dialog>

        <el-dialog :title="dialog.title" :visible.sync="dialog.logVisible " :modal-append-to-body="false"
                   width="800px">
            <el-row class="item">
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            任务编号：
                        </el-col>
                        <el-col :span="16">
                            <span> {{dialog.row.id}}</span>
                        </el-col>
                    </el-row>
                </el-col>
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            任务分组：
                        </el-col>
                        <el-col :span="16">
                            <span v-if="dialog.row.jobGroup==='DEFAULT'"> 默认 </span>
                            <span v-else-if="dialog.row.jobGroup==='SYSTEM'"> 系统 </span>
                        </el-col>
                    </el-row>
                </el-col>
            </el-row>
            <el-row class="item">
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            任务名称：
                        </el-col>
                        <el-col :span="16">
                            <span>{{dialog.row.jobName}}</span>
                        </el-col>
                    </el-row>
                </el-col>
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            创建时间：
                        </el-col>
                        <el-col :span="16">
                            <span> {{dialog.row.createTime}}</span>
                        </el-col>
                    </el-row>
                </el-col>
            </el-row>
            <el-row class="item">
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            任务状态：
                        </el-col>
                        <el-col :span="16">
                            <span v-if="dialog.row.status==='0'"> 正常 </span>
                            <span v-else-if="dialog.row.status==='1'"> 停止 </span>
                        </el-col>
                    </el-row>
                </el-col>
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            下次执行时间：
                        </el-col>
                        <el-col :span="16">
                            <span> {{dialog.row.nextValidTime}}</span>
                        </el-col>
                    </el-row>
                </el-col>
            </el-row>

            <el-row class="item">
                <el-col :span="4">
                    cron表达式：
                </el-col>
                <el-col :span="20">
                    <span> {{dialog.row.cronExpression}}</span>
                </el-col>
            </el-row>
            <el-row class="item">
                <el-col :span="4">
                    调用字符串：
                </el-col>
                <el-col :span="20">
                    <span> {{dialog.row.invokeTarget}}</span>
                </el-col>
            </el-row>

            <el-row class="item">
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            是否并发：
                        </el-col>
                        <el-col :span="16">
                            <span v-if="dialog.row.concurrent==='0'"> 允许 </span>
                            <span v-else-if="dialog.row.concurrent==='1'"> 禁止 </span>
                        </el-col>
                    </el-row>
                </el-col>
                <el-col :span="12">
                    <el-row>
                        <el-col :span="8">
                            执行策略：
                        </el-col>
                        <el-col :span="16">
                            <span v-if="dialog.row.misfirePolicy==='0'"> 默认 </span>
                            <span v-else-if="dialog.row.misfirePolicy==='1'"> 立即执行 </span>
                            <span v-else-if="dialog.row.misfirePolicy==='2'"> 执行一次 </span>
                            <span v-else-if="dialog.row.misfirePolicy==='3'"> 放弃执行 </span>
                        </el-col>
                    </el-row>
                </el-col>

            </el-row>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialog.logVisible = false" size="medium">取 消</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script lang="ts">
    import {Component, Ref, Vue} from 'vue-property-decorator';
    import {addJob, checkCronExpressionIsValid, exportJob, getJobList, removeJob, runJob, updateJob} from '@/api/job';
    import DataTable from '@/components/DataTable/DataTable.vue';
    import {validateForm} from '@/utils';

    @Component({
        components: {
            DataTable
        }
    })
    export default class Job extends Vue {
        @Ref('dataTable') private dataTable: any;
        @Ref('selectForm') private selectForm: any;
        @Ref('jobForm') private jobForm: any;
        private getJobList: Function = getJobList;


        selectFormModel: any = {
            jobName: '',
            jobGroup: '',
            status: '',
        };

        dialog: any = {
            dialogFormVisible: false,
            title: '对话框',
            isEdit: false,
            isBatchEditDisabled: true,
            isBatchRemoveDisabled: true,
            formData: [],
            logVisible: false,
            row: {}
        };

        jobModel: any = {
            jobName: '',
            jobGroup: 'DEFAULT',
            invokeTarget: '',
            cronExpression: '',
            misfirePolicy: '1',
            concurrent: '1',
            status: '1',
            remark: ''
        };

        jobFormRules: any = {
            jobName: [
                {required: true, message: '任务名称不能为空', trigger: ['blur', 'change']},
            ],
            jobGroup: [
                {required: true, message: '任务分组不能为空', trigger: ['blur', 'change']},
            ],
            invokeTarget: [
                {required: true, message: '调用目标字符串不能为空', trigger: ['blur', 'change']},
            ],
            cronExpression: [
                {required: true, message: 'cron表达式不能为空', trigger: ['blur', 'change']},
                {validator: this.validateCronExpressionIsValid, trigger: 'blur'}
            ]
        };

        columns: any = [
            {label: 'ID', prop: 'id', sortable: 'custom'},
            {label: '任务名称', prop: 'jobName', sortable: 'custom'},
            {
                label: '任务分组', prop: 'jobGroup', sortable: 'custom', render: function (createElement, row) {
                    if (row && row.row && row.row.jobGroup === 'DEFAULT') {
                        return createElement('el-tag', {
                                attrs: {
                                    type: 'success'
                                }
                            }, ['默认']
                        );
                    } else if (row && row.row && row.row.jobGroup === 'SYSTEM') {
                        return createElement('el-tag', {
                                attrs: {
                                    type: 'warning'
                                }
                            }, ['系统']
                        );
                    } else {
                        return createElement('el-tag', {
                                attrs: {
                                    type: 'danger'
                                }
                            }, ['未知']
                        );
                    }
                }
            },
            {label: '调用目标字符串', prop: 'invokeTarget', sortable: 'custom', showOverflowTooltip: true},
            {label: '执行表达式', prop: 'cronExpression', sortable: 'custom'},
            {label: '任务状态', prop: 'status', sortable: 'custom'},
            {label: '创建时间', prop: 'createTime', sortable: 'custom', width: 160}
        ];

        /*table 的参数*/
        options: any = {
            stripe: true, // 是否为斑马纹 table
            loading: false, // 是否添加表格loading加载动画
            highlightCurrentRow: true, // 是否支持当前行高亮显示
            multipleSelect: true, // 是否支持列表项选中功能
        };


        /*操作栏*/
        operates: any = {
            width: 'auto',
            fixed: 'right',
            list: [
                {
                    label: '编辑',
                    type: 'warning',
                    icon: 'el-icon-edit',
                    plain: true,
                    disabled: (index, row) => {
                        return false;
                    },
                    permission: 'monitor:job:edit',
                    method: (index, row) => {
                        this.handleEdit(index, row);
                    }
                },
                {
                    label: '删除',
                    type: 'danger',
                    icon: 'el-icon-delete',
                    plain: true,
                    disabled: (index, row) => {
                        return false;
                    },
                    permission: 'monitor:job:remove',
                    method: (index, row) => {
                        this.handleDelete(index, row);
                    }
                },
                {
                    label: '执行一次',
                    type: 'success',
                    icon: 'el-icon-video-play',
                    plain: true,
                    disabled: (index, row) => {
                        return false;
                    },
                    permission: 'monitor:job:changeStatus',
                    method: (index, row) => {
                        this.handleExec(index, row);
                    }
                },
                {
                    label: '详细',
                    type: 'info',
                    icon: 'el-icon-info',
                    plain: true,
                    disabled: (index, row) => {
                        return false;
                    },
                    permission: 'monitor:job:detail',
                    method: (index, row) => {
                        this.handleLog(index, row);
                    }
                }
            ]
        };

        /*校验cron表达式是否有效*/
        validateCronExpressionIsValid(rule: any, value: any, callback: any) {
            console.log(value);
            checkCronExpressionIsValid({
                cronExpression: value
            }).then((res: any) => {
                if (res.data && res.data === true) {
                    callback();
                } else {
                    callback(new Error('cron表达式不合法'));
                }
            }).catch((err: any) => {
                console.log(err);
                callback(new Error('cron表达式不合法'));
            })
        }

        /*新增*/
        handleAdd() {
            this.dialog.title = '新增调度任务';
            this.dialog.isEdit = false;
            this.dialog.dialogFormVisible = true;
            this.dialog.logVisible = false;
        }

        /*编辑*/
        handleEdit(index: number, row: any) {
            this.jobModel = Object.assign({}, row || this.dialog.formData[0]);
            this.dialog.title = '编辑调度任务';
            this.dialog.isEdit = true;
            this.dialog.dialogFormVisible = true;
            this.dialog.logVisible = false;
        }

        /*批量删除*/
        handleBatchDelete() {
            //删除
            this.$confirm('确定要删除选定调度任务吗？', '警告', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                const ids: Array<any> = [];
                this.dialog.formData.forEach((item, index) => {
                    ids[index] = item.id;
                });
                return removeJob({'ids': ids});
            }).then((response: any) => {
                this.dataTable.refresh();
                this.$message.success(response.msg);
            }).catch((e) => {
                console.log(e);
            });
        }

        /*任务日志*/
        handleJobLogsInfo() {
            this.$router.push('/monitor/jobLog').catch((e) => {
                console.log(e);
            });
        }

        /*删除*/
        handleDelete(index: number, row: any) {
            this.$confirm('确定要删除该调度任务吗？', '警告', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                return removeJob({'ids': [row.id]});
            }).then((response: any) => {
                this.dataTable.refresh();
                this.$message.success(response.msg);
            }).catch((e) => {
                console.log(e);
            });
        }

        /*调用执行一次*/
        handleExec(index: number, row: any) {
            this.$confirm('确定要立即执行一次吗？', '警告', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                return runJob({'id': row.id, 'jobGroup': row.jobGroup});
            }).then((response: any) => {
                this.dataTable.refresh();
                this.$message.success(response.msg);
            }).catch((e) => {
                console.log(e);
            });
        }

        /*任务详情*/
        handleLog(index: number, row: any) {
            this.dialog.logVisible = true;
            this.dialog.dialogVisible = false;
            this.dialog.row = row;
            this.dialog.title = '任务详细';
        }

        /*导出excel*/
        handleExport(): void {
            this.$confirm('确定要导出当前查询的所有调度任务信息吗？', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'info'
            }).then(() => {
                this.selectFormModel.pageNum = null;
                this.selectFormModel.pageSize = null;
                this.selectFormModel.orderByColumn = 'id';
                this.selectFormModel.isAsc = 'asc';

                return exportJob(this.selectFormModel);
            }).then((response: any) => {
                console.log(response);
                if (response && response.data) {
                    (this as any).$download(response.data.fileName);
                }
            }).catch((e) => {
                console.log(e);
            });
        }

        submitForm(): void {
            this.jobForm.validate((valid: boolean) => {
                if (valid) {
                    if (this.dialog.isEdit) {
                        //编辑
                        updateJob(this.jobModel).then((response: any) => {
                            this.dataTable.refresh();
                            this.reset();
                            this.dialog.dialogFormVisible = false;
                            this.$message.success(response.msg);
                        }).catch((e) => {
                            console.log(e);
                            validateForm(e.data, this.jobForm, this.jobFormRules);
                        });
                    } else {
                        //新增
                        addJob(this.jobModel).then((response: any) => {
                            this.dataTable.refresh();
                            this.reset();
                            this.dialog.dialogFormVisible = false;
                            this.$message.success(response.msg);
                        }).catch((e) => {
                            console.log(e);
                            validateForm(e.data, this.jobForm, this.jobFormRules);
                        });
                    }
                }
            });
        }


        /*搜索*/
        onSearch(): void {
            this.dataTable.refresh();
        }

        /*重置*/
        onRefreshSelectForm(): void {
            //恢复搜索默认信息
            this.selectForm.resetFields();
            this.onSearch();
        }


        /*选中事件*/
        handleSelectionChange(val): void {
            if (val) {
                this.dialog.isBatchRemoveDisabled = val.length <= 0;
                this.dialog.isBatchEditDisabled = val.length !== 1;
            }
            this.dialog.formData = val;
        }

        /*重置表单*/
        reset(): void {
            this.jobModel = {
                jobName: '',
                jobGroup: 'DEFAULT',
                invokeTarget: '',
                cronExpression: '',
                misfirePolicy: '1',
                concurrent: '1',
                status: '1',
                remark: ''
            };
            (this as any).resetForm('jobForm');
        }

        /*关闭对话框*/
        closeDialog() {
            this.$nextTick(() => {
                this.reset();
            });
        }
    }
</script>

<style scoped lang="scss">
    .tableRow {
        .el-dialog__body {
            .item {
                margin-bottom: 18px;
            }
        }
    }
</style>

